package cn.itsource.user.service.impl;

import cn.itsource.basic.contants.SystemContants;
import cn.itsource.basic.contants.WxConstants;
import cn.itsource.basic.service.impl.BasicServiceImpl;
import cn.itsource.basic.util.AjaxResult;
import cn.itsource.basic.util.HttpClientUtils;
import cn.itsource.basic.util.MD5Utils;
import cn.itsource.user.domain.LoginInfo;
import cn.itsource.user.domain.User;
import cn.itsource.user.domain.WxUser;
import cn.itsource.user.mapper.LoginInfoMapper;
import cn.itsource.user.mapper.UserMapper;
import cn.itsource.user.mapper.WxUserMapper;
import cn.itsource.user.service.IUserService;
import cn.itsource.user.service.IWxUserService;
import cn.itsource.user.vo.UserVO;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.TimeUnit;

@Service
public class WxUserServiceImpl extends BasicServiceImpl<WxUser> implements IWxUserService {

    @Autowired
    private WxUserMapper wxUserMapper;

    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private LoginInfoMapper loginInfoMapper;

    @Autowired
    private UserMapper userMapper;

    @Override
    public AjaxResult wxLogin(Map<String, String> map) {
        String code = map.get("code");
        //1.根据code获取对应的 openid  access_token --调用微信三方接口
        String url= WxConstants.GET_ACK_URL;
        String replace = url.replace("APPID", WxConstants.APPID)
                .replace("SECRET", WxConstants.SECRET)
                .replace("CODE", code);
        //发起请求
        String result = HttpClientUtils.httpGet(replace);
        //{"access_token":"42_eL9a7NWl1MXKeZbx_24rPLHHdhUAnfJqRtYssrFUeYafBW4KTeG_6hltmfJGsaK2vp6_tyh6a3t24t6kOfM4me-3IrFzyWSk1ywLbCJRXCg","expires_in":7200,"refresh_token":"42_11njNI_6BTYGxAzVQg7n7yYPxngdAbKEa2d-9mc9ZMjKuOcE9ALCMFeSAqXp_sdwZgtuQ17qQE3H2rTKqZFkUsykitWCQM8Wy1Y80fXMQDg",
        //"openid":"oa9wA04vls5LyNhIQ8ZYJ6y1RkR4",
         //"scope":"snsapi_login","unionid":"ovnCWwxkm6xnTup_3yGyBJJzg9sU"}
        JSONObject jsonObject = JSON.parseObject(result);
        //获取openid
        String openid = jsonObject.getString("openid");
        String access_token = jsonObject.getString("access_token");
        //2.根据openid查询t_wxuser
        WxUser wxUser = wxUserMapper.loadByOpenId(openid);
        //2.1 获取到wxuser对象
        //用户的信息完善 直接登录
        if (wxUser!=null && wxUser.getUser()!=null){
            //完成免密登录
            //1.生成一个 token  （本质就是一个字符串）
            String token = UUID.randomUUID().toString();
            LoginInfo loginInfo = loginInfoMapper.loadById(wxUser.getUser().getLogininfo_id());
            //2.放到redis
            redisTemplate.opsForValue().set(token, loginInfo, 30, TimeUnit.MINUTES);
            //3.把token返回给前端用户，把当前的登录用户返回给前端
            Map<String,Object> resultMap = new HashMap<>();
            resultMap.put("token", token);
            //为了安全 把salt和password抹除
            loginInfo.setSalt(null);
            loginInfo.setPassword(null);
            resultMap.put("loginInfo", loginInfo);
            //返回给前端用户
            return AjaxResult.me().setResultObj(resultMap);
        }
        //2.2 跳转到绑定页面
        //用户区分到底是跳转页面还是 登录成功
        String bindUrl = "/binder.html?openid="+openid+"&access_token="+access_token;
        return AjaxResult.me().setMessage(bindUrl);
    }

    //绑定的逻辑
    @Override
    public AjaxResult binder(Map<String, String> map) {// phone  code
        String phone = map.get("phone");
        String code = map.get("code");
        String openid = map.get("openid");
        String access_token = map.get("access_token");
        //非空验证
        if (StringUtils.isEmpty(phone) || StringUtils.isEmpty(code)) {
            throw  new RuntimeException("请完善数据");
        }
        //验证code有效性
        Object oCode = redisTemplate.opsForValue().get(phone + ":" + SystemContants.BINDER);
        if (oCode==null){
            throw  new RuntimeException("验证码已失效，请重新获取");
        }else {
            String strCode =  (String)oCode;
            //取出redis里面的验证码
            String redisCode = strCode.split(":")[0];
            if (!redisCode.equals(code)){
                throw  new RuntimeException("验证码错误，请重新输入");
            }
        }
        //获取微信的用户信息
        String url = WxConstants.GET_USER_URL.replace("ACCESS_TOKEN", access_token)
                .replace("OPENID", openid);
        String resultJson = HttpClientUtils.httpGet(url);
        //json转对象
        JSONObject jsonObject = JSON.parseObject(resultJson);


        //1.确认用户微信用户是否存在
        WxUser wxUser = wxUserMapper.loadByOpenId(openid);
        if (wxUser==null){
            //wx用户为空
            wxUser = new WxUser();
            wxUser.setOpenid(openid);
            //获取昵称
            wxUser.setNickname(jsonObject.getString("nickname"));
            wxUser.setHeadimgurl(jsonObject.getString("headimgurl"));
            wxUser.setSex(jsonObject.getInteger("sex"));
            wxUser.setUnionid(jsonObject.getString("unionid"));
            //保存用户
        }

        //根据用户类型和 手机号获取用户
        LoginInfo loginInfo = loginInfoMapper.loadByPhone(phone,1);
        User user =userMapper.loadByPhone(phone);
        if(loginInfo==null&&user==null){
            // 添加一条 t_user表的数据
            user = new User();
            user.setPhone(phone);
            user.setState(1);
            user.setHeadImg(wxUser.getHeadimgurl());
            // 添加一条t_loginInfo
            loginInfo = new LoginInfo();
            BeanUtils.copyProperties(user, loginInfo);
            //状态 与类型
            loginInfo.setType(1);
            loginInfo.setDisable(1);

            //先保存logininfo
            loginInfoMapper.save(loginInfo);
            //设置关联信息
            user.setLogininfo_id(loginInfo.getId());
            //再保存用户
            userMapper.save(user);
        }
        //保存微信用户
        wxUser.setUser(user);
        wxUserMapper.save(wxUser);

        //4.免密登录
        //1.生成一个 token  （本质就是一个字符串）
        String token = UUID.randomUUID().toString();
        //2.放到redis
        redisTemplate.opsForValue().set(token, loginInfo, 30, TimeUnit.MINUTES);
        //3.把token返回给前端用户，把当前的登录用户返回给前端
        Map<String,Object> resultMap = new HashMap<>();
        resultMap.put("token", token);
        //为了安全 把salt和password抹除
        loginInfo.setSalt(null);
        loginInfo.setPassword(null);
        resultMap.put("loginInfo", loginInfo);
        //返回给前端用户
        return AjaxResult.me().setResultObj(resultMap);
    }
}
